package com.personal.sfe.token;

import cn.hutool.core.util.IdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author: 梁奔
 * @date: 2025/11/04
 */

/**
 * TokenService类 - 提供令牌生成、验证和管理功能的服务类
 * 使用Redis存储令牌信息，实现快速有效的令牌管理
 */
@Service
public class TokenService {
    // Redis操作模板，用于与Redis数据库交互
    @Autowired
    private StringRedisTemplate redisTemplate;
    // 令牌前缀，用于在Redis中区分不同类型的键
    private static final String TOKEN_PREFIX = "auth:token:";

    @Value("${auth.token.expiration}")
    private long tokenExpiration;


    /**
     * 生成新的认证令牌
     *
     * @param username 用户名，将与令牌关联
     * @return 生成的UUID格式令牌字符串
     */
    public String generateToken(String username) {
        // 使用工具类生成简单UUID作为令牌
        String token = IdUtil.simpleUUID();
        // 构建Redis存储键
        String key = TOKEN_PREFIX + token;
        // 将令牌和用户名存入Redis，设置过期时间
        redisTemplate.opsForValue().set(key, username, tokenExpiration, TimeUnit.SECONDS);
        return token;
    }

    /**
     * 根据令牌获取关联的用户名
     *
     * @param token 认证令牌
     * @return 关联的用户名，如果令牌不存在则返回null
     */
    public String getUsernameByToken(String token) {
        // 构建Redis存储键
        String key = TOKEN_PREFIX + token;
        // 从Redis中获取令牌关联的用户名
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 验证令牌是否有效
     *
     * @param token 待验证的令牌
     * @return 如果令牌存在且有效返回true，否则返回false
     */
    public boolean validateToken(String token) {
        // 构建Redis存储键
        String key = TOKEN_PREFIX + token;
        // 检查Redis中是否存在该令牌
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 使令牌失效，即从Redis中删除
     *
     * @param token 要失效的令牌
     */
    public void invalidateToken(String token) {
        // 构建Redis存储键
        String key = TOKEN_PREFIX + token;
        // 从Redis中删除令牌
        redisTemplate.delete(key);
    }
}
